package com.sproutcat.security;

import org.springframework.util.Base64Utils;
import org.springframework.util.StreamUtils;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
import java.util.Base64;

import static java.nio.charset.StandardCharsets.UTF_8;

/**
 * AES 对称加密用例
 *
 * @author tzg
 */
public class AesSample {

    public static void main(String[] args) throws Exception {
        InputStream is = RsaSample.class.getResourceAsStream("/test.json");
        String testDate = StreamUtils.copyToString(is, UTF_8);
//        String testDate = "[{\n" +
//                "  \"name\": \"test1\",\n" +
//                "  \"age\": 21\n" +
//                "},{\n" +
//                "  \"name\": \"test2\",\n" +
//                "  \"age\": 26\n" +
//                "}]";
        //String testDate = "Hello world!";

        String key = randomAesKey();
        String encryptDate = encrypt(testDate, key);
        System.out.println("AES 公钥加密结果: " + encryptDate);
        System.out.println();
        System.out.println("AES 私钥解密结果: " + decrypt(encryptDate, key));
    }

    //=========================== AES 基础代码 =============================================
    public static final String KEY_ALGORITHM = "AES";
    private final static String KEY_TRANSFORMATION = "AES/ECB/PKCS5Padding";

    /**
     * 生成AES256随机密钥
     *
     * @return
     */
    public static String randomAesKey() {
        String stringSet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        SecureRandom random = new SecureRandom();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 32; i++) {
            int number = random.nextInt(stringSet.length());
            sb.append(stringSet.charAt(number));
        }
        return sb.toString();
    }

    /**
     * AES 256 ECB 加密
     *
     * @param plaintext
     * @param key
     * @return
     * @throws Exception
     */
    public static String encrypt(String plaintext, String key) throws GeneralSecurityException {
        if (plaintext == null || "".equals(plaintext)) {
            return "";
        }
        Cipher cipher = Cipher.getInstance(KEY_TRANSFORMATION);
        SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(UTF_8), KEY_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
        byte[] encrypted = cipher.doFinal(plaintext.getBytes(UTF_8));
        return new String(Base64.getEncoder().encode(encrypted), UTF_8);
    }


    /**
     * AES 256 ECB 解密
     *
     * @param ciphertext
     * @param key
     * @return
     */
    public static String decrypt(String ciphertext, String key) throws GeneralSecurityException {
        Cipher cipher = Cipher.getInstance(KEY_TRANSFORMATION);
        SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(UTF_8), KEY_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, skeySpec);
        byte[] encrypted = Base64.getDecoder().decode(ciphertext.getBytes(UTF_8));
        byte[] original = cipher.doFinal(encrypted);
        return new String(original, UTF_8);
    }

}
